Amazon SQS
https://gyazo.com/c60e3d5a12082f60091bdfade2056f9e
Amazon Simple Queue Service
マネージドなMessage Queueサービス
#WIP
2種類のqueueがある
標準キュー
FIFOキュー
最大14日間メッセージをキューに保持できる
https://speakerdeck.com/pikosan0000/sqs-lambda-devday2022
AWS Lambdaと組み合わせる
/mrsekut-book-486354314X/036
gpt-5.icon
概要
マネージドなメッセージキュー
送信側(Producer)と受信側(Consumer)を疎結合にして、スパイク吸収・再試行・バックプレッシャーを実現。
2タイプ
Standard:高スループット、少なくとも一度配信(重複あり得る)、ベストエフォート順序。最も一般的。
FIFO:順序保証+重複排除(exactly-once 処理)。キュー名は必ず .fifo。メッセージグループ単位で順序を保つ。
基本パラメータ
Visibility Timeout(既定 30s):取り出し後、他のコンシューマから見えなくする時間。処理時間に合わせて設定。
Long Polling(最大 20s):空打ちを減らし料金最適化。receive_wait_time_seconds を設定。
Message Retention:保持期間(最大 14 日)。
最大ペイロード 256KB(大きいデータは S3 へ、S3 のキーをメッセージに載せるのが定石)。
エラーハンドリング
DLQ(デッドレターキュー):一定回数失敗したメッセージを隔離し、後で調査・再処理。
セキュリティ / 運用
サーバサイド暗号化(SSE)対応、IAM / キューポリシーでアクセス制御、CloudWatch で可視化。
Terraform サンプル
まずは Standard + DLQ の最小構成、それから FIFO の例を載せます。
1) Standard Queue + DLQ
code:hcl(rb)
# DLQ(失敗メッセージの避難先)
resource "aws_sqs_queue" "orders_dlq" {
name = "orders-dlq"
message_retention_seconds = 1209600 # 14 days
sqs_managed_sse_enabled = true
}
# 本番キュー(Standard)
resource "aws_sqs_queue" "orders" {
name = "orders"
visibility_timeout_seconds = 60 # 処理にかかる想定時間に合わせる
receive_wait_time_seconds = 20 # Long Polling
message_retention_seconds = 345600 # 4 days
sqs_managed_sse_enabled = true
# 失敗を DLQ に逃がす
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.orders_dlq.arn
maxReceiveCount = 5 # 5回失敗したら DLQ へ
})
}
# 例:特定の IAM ロールからの Send/Receive を許可するポリシー(任意)
data "aws_iam_policy_document" "orders_policy" {
statement {
sid = "AllowFromAppRole"
effect = "Allow"
actions = "sqs:SendMessage", "sqs:ReceiveMessage", "sqs:DeleteMessage", "sqs:GetQueueAttributes"
principals {
type = "AWS"
identifiers = "arn:aws:iam::123456789012:role/app-svc-role"
}
resources = aws_sqs_queue.orders.arn
}
}
resource "aws_sqs_queue_policy" "orders" {
queue_url = aws_sqs_queue.orders.id
policy = data.aws_iam_policy_document.orders_policy.json
}
resource "aws_sqs_queue"
resource "aws_sqs_queue_policy"
2) FIFO Queue(順序保証 & 重複排除)
code:hcl(rb)
resource "aws_sqs_queue" "payments_fifo" {
name = "payments.fifo" # .fifo 必須
fifo_queue = true
content_based_deduplication = true # 本文ハッシュで重複排除(手動で ID 指定も可)
deduplication_scope = "messageGroup" # or "queue"
fifo_throughput_limit = "perMessageGroupId" # or "perQueue"
receive_wait_time_seconds = 20
visibility_timeout_seconds = 60
sqs_managed_sse_enabled = true
}
利用のイメージ(最小の送受信)
Standard キューでも FIFO でも同じですが、**FIFO では MessageGroupId(必須)と(必要なら)MessageDeduplicationId**を付けます。
送信(Producer)
code:ts
// npm i @aws-sdk/client-sqs
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
const client = new SQSClient({ region: "ap-northeast-1" });
const queueUrl = process.env.ORDERS_QUEUE_URL!; // 例: Terraform 出力から渡す
async function sendOrder(order: { id: string; items: string[] }) {
const cmd = new SendMessageCommand({
QueueUrl: queueUrl,
MessageBody: JSON.stringify(order),
// FIFO の場合のみ(Standardなら不要)
// MessageGroupId: "order-events",
// MessageDeduplicationId: order.id, // content_based_deduplication=false の時
});
await client.send(cmd);
}
受信 & 処理(Consumer)
code:ts(ts)
import {
SQSClient,
ReceiveMessageCommand,
DeleteMessageBatchCommand,
} from "@aws-sdk/client-sqs";
const client = new SQSClient({ region: "ap-northeast-1" });
const queueUrl = process.env.ORDERS_QUEUE_URL!;
async function pollAndProcess() {
const resp = await client.send(new ReceiveMessageCommand({
QueueUrl: queueUrl,
MaxNumberOfMessages: 10,
WaitTimeSeconds: 20, // Long Polling
VisibilityTimeout: 60, // 処理に必要な秒数
}));
if (!resp.Messages?.length) return;
// ここで順次処理(例外時は throw せず可観測化+再試行が原則)
for (const m of resp.Messages) {
const payload = JSON.parse(m.Body!);
// TODO: ビジネスロジック
}
// 正常に処理できたら削除(取りこぼすと再配信される)
await client.send(new DeleteMessageBatchCommand({
QueueUrl: queueUrl,
Entries: resp.Messages.map((m) => ({
Id: m.MessageId!,
ReceiptHandle: m.ReceiptHandle!,
})),
}));
}
設計のコツ(実務ポイント)
Visibility Timeout = 処理時間 + 余裕:短すぎると二重処理、長すぎると遅延が溜まる。
Idempotency(冪等):重複は起こり得る前提(特に Standard)。処理側に冪等性キーを持たせる。
DLQ 運用:DLQ の監視 → エラー分類 → 再処理(手動/ツール)動線を用意。
大きなペイロードは S3:S3 に置いてキーだけ送る。
メトリクス:ApproximateNumberOfMessagesVisible / NotVisible、AgeOfOldestMessage を CloudWatch 監視。
スループット:FIFO はメッセージグループ単位で直列化。並列度は「グループ数」で出す発想。